#include <SGE.h>
#include "Bullet.h"
#include "Enemy.h"
#include "Fighter.h"

using namespace SGE;

const int kMaxBullet = 100;
const int kMaxEnemy = 100;
const int kMaxExplosions = 100;

bool quit = false;
Bullet bullets [kMaxBullet];
Enemy enemies [kMaxBullet];
Fighter fighter;
SGE_Emitter explosions [kMaxExplosions];
SGE_Sprite background;
SGE_Sound fireSound;
SGE_Sound explosionSound;
float spawnDelay = 0.0f;
int bulletIndex = 0;
int enemyIndex = 0;
int explosionIndex = 0;

void UpdateGameObjects (float deltaTime)
{
	for (int i = 0; i < kMaxBullet; ++i)
	{
		bullets [i].Update (deltaTime);
	}
	for (int i = 0; i < kMaxEnemy; ++i)
	{
		enemies [i].Update (deltaTime);
	}
	for (int i = 0; i < kMaxExplosions; ++i)
	{
		explosions [i].Update (deltaTime);
	}

	fighter.Update (deltaTime);
}
void FireBullets ()
{
	if (Input_IsKeyPressed (Keys::SPACE))
	{
		if (!bullets [bulletIndex].IsActive ())
		{
			SVector2 pos = fighter.GetPosition ();
			SVector2 vel (0.0f, -500.0f);

			bullets [bulletIndex].Fire (pos, vel);
			bulletIndex = (bulletIndex + 1) % kMaxBullet;
		}
		if (!bullets [bulletIndex].IsActive ())
		{
			SVector2 pos = fighter.GetPosition ();
			SVector2 vel (250.0f, -500.0f);

			bullets [bulletIndex].Fire (pos, vel);
			bulletIndex = (bulletIndex + 1) % kMaxBullet;
		}
		if (!bullets [bulletIndex].IsActive ())
		{
			SVector2 pos = fighter.GetPosition ();
			SVector2 vel (-250.0f, -500.0f);

			bullets [bulletIndex].Fire (pos, vel);
			bulletIndex = (bulletIndex + 1) % kMaxBullet;
		}
		fireSound.Play ();
	}
}
void SpawnEnemies (float deltaTime)
{
	spawnDelay -= deltaTime;

	if (spawnDelay <= 0)
	{
		//It's time to spawn!
		if (!enemies [enemyIndex].IsActive ())
		{
			SVector2 pos ((IniFile_GetInt ("WinWidth", 800) * RandomFloat (0.1f, 1.0f)), 0.0f);

			enemies [enemyIndex].Spawn (pos);
			enemyIndex = (enemyIndex + 1) % kMaxEnemy;
		}

		//Reset delay time
		spawnDelay = RandomFloat (0.5f, 2.0f);
	}
}
void CheckCollision ()
{
	//look through pool of enemies
	for (int e = 0; e < kMaxEnemy; ++e)
	{
		//check if current enemy is active
		if (enemies [e].IsActive ())
		{
			//look through pool of bullets
			for (int b = 0; b < kMaxBullet; ++b)
			{
				//check if current bullet is active
				if (bullets [b].IsActive ())
				{
					SCircle eCircle = enemies [e].GetBoundingCircle ();
					SCircle bCircle = bullets [b].GetBoundingCircle ();

					float xDiff = (eCircle.center.x - bCircle.center.x);
					float yDiff = (eCircle.center.y - bCircle.center.y);
					float dist = sqrt ((xDiff * xDiff) + (yDiff * yDiff));
					float radii = (eCircle.radius + bCircle.radius);

					//compare distance between obj with collision box radii
					if (dist <= radii)
					{
						//kill both enemy and bullet
						enemies [e].Kill ();
						bullets [b].Kill ();

						explosionSound.Play ();

						//create an explosion when enemy dies
						explosions [explosionIndex].SetPosition (eCircle.center);
						explosions [explosionIndex].Start (100.0f, true);
						explosionIndex = ((explosionIndex + 1) % kMaxExplosions);

						break;
					}
				}
			}
		}
	}
}

void SGE_Initialize ()
{
	background.Load ("space.jpg");
	SVector2 center ((IniFile_GetInt ("WinWidth", 800) * 0.5f), (IniFile_GetInt ("WinHeight", 600) * 0.6f));

	fighter.Load ();
	fighter.SetPosition (center);

	for (int i = 0; i < kMaxBullet; ++i)
	{
		bullets [i].Load ();
	}
	for (int i = 0; i < kMaxEnemy; ++i)
	{
		enemies [i].Load ();
	}
	for (int i = 0; i < kMaxExplosions; ++i)
	{
		explosions [i].Load ("explosion.txt");
	}

	fireSound.Load ("photongun1.wav");
	explosionSound.Load ("explosion.wav");
}

void SGE_Render ()
{
	background.Render ();

	for (int i = 0; i < kMaxEnemy; ++i)
	{
		enemies [i].Render ();
	}
	for (int i = 0; i < kMaxBullet; ++i)
	{
		bullets [i].Render ();
	}
	for (int i = 0; i < kMaxExplosions; ++i)
	{
		explosions [i].Render (true);
	}

	fighter.Render ();
}

void SGE_Terminate ()
{
	for (int i = 0; i < kMaxBullet; ++i)
	{
		bullets [i].Unload ();
	}
	for (int i = 0; i < kMaxEnemy; ++i)
	{
		enemies [i].Unload ();
	}
	fighter.Unload ();
	for (int i = 0; i < kMaxExplosions; ++i)
	{
		explosions [i].Unload ();
	}
	fireSound.Unload ();
	explosionSound.Unload ();
	background.Unload ();
}

bool SGE_Update (float deltaTime)
{
	UpdateGameObjects (deltaTime);
	FireBullets ();
	SpawnEnemies (deltaTime);
	CheckCollision ();

	if (Input_IsKeyPressed (Keys::ESCAPE))
	{
		quit = true;
	}

	return quit;
}